package ru.batrdmi.svnplugin.logic;

import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.io.*;

import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

public class TimedSVNRepositoryWrapper extends SVNRepository {
    private final SVNRepository repo;
    private final StopWatch repoAccess = new StopWatch("repo access");
    private final StopWatch cacheAccess = new StopWatch("repo+cache access estimate");

    protected TimedSVNRepositoryWrapper(SVNRepository repo) {
        super(null, null);
        this.repo = repo;
    }

    @Override
    public void testConnection() throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public long getLatestRevision() throws SVNException {
        repoAccess.start("getLatestRevision()");
        long result = repo.getLatestRevision();
        repoAccess.stop();
        return result;
    }

    @Override
    public long getDatedRevision(Date date) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNProperties getRevisionProperties(long l, SVNProperties svnProperties) throws SVNException {
        repoAccess.start("getRevisionProperties(" + l + "," + svnProperties + ")");
        SVNProperties result = repo.getRevisionProperties(l, svnProperties);
        repoAccess.stop();
        return result;
    }

    @Override
    public long log(String[] targetPaths, long startRevision, long endRevision, boolean discoverChangedPaths, boolean strictNodeHistory, long limit, boolean includeMergedRevisions, String[] revisionProperties, ISVNLogEntryHandler handler) throws SVNException {
        repoAccess.start("log(" + Arrays.toString(targetPaths) + "," + startRevision + "," + endRevision + "," + discoverChangedPaths + "," + strictNodeHistory + "," + limit + "," + includeMergedRevisions + "," + Arrays.toString(revisionProperties) + "," + handler + ")");
        long result = repo.log(targetPaths, startRevision, endRevision, discoverChangedPaths, strictNodeHistory, limit, includeMergedRevisions, revisionProperties, handler);
        repoAccess.stop();
        cacheAccess.start("*log(" + Arrays.toString(targetPaths) + "," + startRevision + "," + endRevision + ",false," + strictNodeHistory + "," + limit + "," + includeMergedRevisions + ",null,emptyHandler)");
        repo.log(targetPaths, startRevision, endRevision, false, strictNodeHistory, limit, includeMergedRevisions, null, new ISVNLogEntryHandler() {
            @Override
            public void handleLogEntry(SVNLogEntry svnLogEntry) throws SVNException {
                // ignore
            }
        });
        cacheAccess.stop();
        return result;
    }

    @Override
    public void setRevisionPropertyValue(long l, String s, SVNPropertyValue svnPropertyValue) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNPropertyValue getRevisionPropertyValue(long l, String s) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNNodeKind checkPath(String s, long l) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public long getFile(String s, long l, SVNProperties svnProperties, OutputStream outputStream) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public long getDir(String s, long l, SVNProperties svnProperties, ISVNDirEntryHandler isvnDirEntryHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public long getDir(String s, long l, SVNProperties svnProperties, int i, ISVNDirEntryHandler isvnDirEntryHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNDirEntry getDir(String s, long l, boolean b, Collection collection) throws SVNException {
        repoAccess.start("getDir(" + s + "," + l + "," + b + "," + collection + ")");
        SVNDirEntry result = repo.getDir(s, l, b, collection);
        repoAccess.stop();
        return result;
    }

    @Override
    public void diff(SVNURL svnurl, long l, long l1, String s, boolean b, SVNDepth svnDepth, boolean b1, ISVNReporterBaton isvnReporterBaton, ISVNEditor isvnEditor) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void update(SVNURL svnurl, long l, String s, SVNDepth svnDepth, ISVNReporterBaton isvnReporterBaton, ISVNEditor isvnEditor) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void update(long l, String s, SVNDepth svnDepth, boolean b, ISVNReporterBaton isvnReporterBaton, ISVNEditor isvnEditor) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void status(long l, String s, SVNDepth svnDepth, ISVNReporterBaton isvnReporterBaton, ISVNEditor isvnEditor) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void replay(long l, long l1, boolean b, ISVNEditor isvnEditor) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNDirEntry info(String s, long l) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public ISVNEditor getCommitEditor(String s, Map map, boolean b, ISVNWorkspaceMediator isvnWorkspaceMediator) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    protected ISVNEditor getCommitEditorInternal(Map map, boolean b, SVNProperties svnProperties, ISVNWorkspaceMediator isvnWorkspaceMediator) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNLock getLock(String s) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public SVNLock[] getLocks(String s) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void lock(Map map, String s, boolean b, ISVNLockHandler isvnLockHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void unlock(Map map, boolean b, ISVNLockHandler isvnLockHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void closeSession() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean hasCapability(SVNCapability svnCapability) throws SVNException {
        repoAccess.start("hasCapability(" + svnCapability + ")");
        boolean result = repo.hasCapability(svnCapability);
        repoAccess.stop();
        return result;
    }

    @Override
    protected long getDeletedRevisionImpl(String s, long l, long l1) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    public long getDeletedRevision(String s, long l, long l1) throws SVNException {
        repoAccess.start("getDeletedRevision(" + s + "," + l + "," + l1 + ")");
        long result = repo.getDeletedRevision(s, l, l1);
        repoAccess.stop();
        return result;
    }

    @Override
    protected long getLocationSegmentsImpl(String s, long l, long l1, long l2, ISVNLocationSegmentHandler isvnLocationSegmentHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    protected int getLocationsImpl(String s, long l, long[] longs, ISVNLocationEntryHandler isvnLocationEntryHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    protected long logImpl(String[] strings, long l, long l1, boolean b, boolean b1, long l2, boolean b2, String[] strings1, ISVNLogEntryHandler handler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    protected int getFileRevisionsImpl(String s, long l, long l1, boolean b, ISVNFileRevisionHandler isvnFileRevisionHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    protected Map getMergeInfoImpl(String[] strings, long l, SVNMergeInfoInheritance svnMergeInfoInheritance, boolean b) throws SVNException {
        throw new UnsupportedOperationException();
    }

    @Override
    protected void replayRangeImpl(long l, long l1, long l2, boolean b, ISVNReplayHandler isvnReplayHandler) throws SVNException {
        throw new UnsupportedOperationException();
    }
    
    public void logTotalTime() {
        repoAccess.logTotalTime();
        cacheAccess.logTotalTime();
    }
}
